#include "head_s.h"

int pipe_fd[2];
void func(int num){
    write(pipe_fd[1], "1", 1);
}
    
int main(){
    char ip[100] = "\0";
    getparameter("ip", ip);

    char port[100] = "\0";
    getparameter("port", port);

    char base_path[100] = "\0";
    getparameter("base_path", base_path);

    char mysql_user[100] = {0};
    getparameter("mysql_user", mysql_user);
    char mysql_password[100] = {0};
    getparameter("mysql_password", mysql_password);
    char mysql_database[100] = {0};
    getparameter("mysql_database", mysql_database);
    LOG_WRITE(LOG_ERROR,"ip = %s, port = %s", ip, port);

    pipe(pipe_fd);

    if(fork() != 0){
        // 父进程
        signal(2, func);

        wait(NULL);
        exit(0);
    }
    // 子进程
    setpgid(0, 0);

    user_t status;
    portocol_t portocol;

    // 初始化status_t结构体
    status_t statu;
    init_status(&statu, 4);
    

    // 启动子线程
    init_thread(&statu);

    // 创建三次握手的socket
    int socket_fd;
    init_socket(&socket_fd, port, ip);

    int epoll_fd = epoll_create(1);

    add_epoll(epoll_fd, socket_fd);

    add_epoll(epoll_fd, pipe_fd[0]);

    pthread_mutex_lock(&statu.lock);
    MYSQL* mysql = mysql_init(NULL);
    mysql_real_connect(mysql,"localhost", mysql_user, mysql_password, mysql_database, 0 ,NULL, 0);
    pthread_mutex_unlock(&statu.lock);

    while(1){


        fflush(stdout);                                                                                       
        memset(&status, 0, sizeof(status));
        sprintf(status.base_path, base_path);
        memset(&portocol, 0, sizeof(portocol));

        struct epoll_event events[2];
        memset(events, 0, sizeof(events));

        int epoll_num = epoll_wait(epoll_fd, events, 2, -1);

        // 遍历就绪集合
        for(int i=0; i<epoll_num; i++){
            int fd = events[i].data.fd;

            if(fd == socket_fd){
                // 新链接进来
                int net_fd = accept(socket_fd, NULL, NULL);
                add_epoll(epoll_fd, net_fd);
            }else if(fd == pipe_fd[0]){
                // 说明有信号过来
                // 通知子线程退出
                pthread_mutex_lock(&statu.lock);
                statu.exit_flag = 1;
                pthread_cond_broadcast(&statu.cond);
                pthread_mutex_unlock(&statu.lock);

                // 等待子线程都退出
                for(int x=0; x<4; x++){
                    pthread_join(statu.thread_ids[x], NULL);
                }

                pthread_exit(NULL);
            }else{
                // 有人发信息过来
                int ret = 0;
                LOG_WRITE(LOG_ERROR, "cmd: %d\n", portocol.cmd);
                ret = read_stdin(&status, &portocol, fd);
                LOG_WRITE(LOG_ERROR, "worker: user_name = %s, path = %s, mima = %s\n", status.user_name, status.path, status.arg);
                LOG_WRITE(LOG_ERROR, "cmd: %d\n", portocol.cmd);
                LOG_WRITE(LOG_ERROR, "ret = %d\n", ret);
                if (ret == 0)
                {
                    break;
                }
                switch(portocol.cmd)
                {
                case CD:
                    cd(&status, &portocol, fd, mysql);
                    break;
                case LS:
                    ls(&status, &portocol, fd, mysql);
                    break;
                case PUTS:
                    pthread_mutex_lock(&statu.lock);
                    enQueue(&statu.queue,fd);
                    pthread_cond_broadcast(&statu.cond);
                    pthread_mutex_unlock(&statu.lock);
                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, events);
                    break;
                case GETS:
                    LOG_WRITE(LOG_ERROR, "11111111111\n");
                    pthread_mutex_lock(&statu.lock);
                    enQueue(&statu.queue, fd);
                    pthread_cond_broadcast(&statu.cond);
                    pthread_mutex_unlock(&statu.lock);
                    epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, events);
                    
                    break;
                case RM:
                    rm(&status, &portocol, fd, mysql);
                    break;
                case MKDIR:
                    create_dir(&status, &portocol, fd, mysql);
                    break;
                case LOGIN:
                    login(&status, &portocol, fd, mysql);
                    break;
                case REGISTER:
                    regist(&status, &portocol, fd, mysql);
                    break;
                }

            }
        }

    }

    return 0;
}

